#include "Game.h"
#include "Player.h"
#include "external/tinyxml.h"
#include "Animacion.h"
#include "Mapa.h"
#include "SenalRuta.h"
#include "PathFinder.h"
#include <iostream>

using namespace std;

Player::Player(ID id, Mapa *m):AnimatedActor(id,Actores::JUGADOR),mapa(m)
	{

		ruta = NULL;

		actual = "Abajo";
		xDestino = x = y = yDestino = 240.f;


		g->getEventos()->addListener(TRIGGER_ENTRADA,this);
		g->getEventos()->addListener(CARGANDO_MAPA,this);
		g->getEventos()->addListener(RATON_BOTON_SOLTADO,this);
		g->getEventos()->addListener(RUTA_GENERADA,this);


		cargarAnimaciones(string("data/actores/player.xml"));

		click = static_cast<Sonido*>(g->getRecursos()->getResource(string("mouseClick.wav"),RECURSOS::SONIDO));
		
	}
bool estaCerca(float var1, float var2, float margen){
	return (var1 + margen > var2 && var1 - margen < var2);
	}

void Player::update( float speedFactor )
	{
	
	if (!enMovimiento()){//si estamos quietos
		animaciones[actual]->stop();
		if (ruta != NULL)// si hay ruta que seguir...
			seguirPath();
		comprobarTeclas();
		
	}
		
	animaciones[actual]->update(speedFactor);

	
	}

void Player::comprobarTeclas(){

	bool *keys = g->getTeclas();

	if (keys['w'] || keys['W'])
		moverDestino(0,-1);
	else if(keys['s'] || keys['S'])
		moverDestino(0,1);
	else if (keys['a'] || keys['A'])
		moverDestino(-1,0);		
	else if (keys['d'] || keys['D'])
		moverDestino(1,0);
		
	}
/** para mover comprobamos que el destino es viable */
void Player::moverDestino( int dirx, int diry, bool enTile)
	{
		
			if (!enMovimiento()){
				
				animaciones[actual]->play();

				int xActual = (int)x/(int)mapa->getAnchoTile();
				int yActual = (int)y/(int)mapa->getAltoTile();

				if (!enTile){//si lo que nos han indicado es una direccion...
					

					if (mapa->esAccesible(xActual + dirx, yActual + diry)){//si el tile es accesible		
						mover((xActual + dirx) * mapa->getAnchoTile(), (yActual + diry) * mapa->getAnchoTile(),MS_POR_TILE);// en pixels
						g->getEventos()->enviarEvento(new Event(ACTOR_MOVIDO,new eventoActorMovido(this,xActual + dirx, yActual + diry)));
						setAnimacion(dirx,diry);
					}
				}else if (mapa->esAccesible(dirx, diry)){//si nos han indicado directamente a que tile ir...
						mover( dirx * mapa->getAnchoTile(), diry * mapa->getAnchoTile(),MS_POR_TILE);// en pixels
						g->getEventos()->enviarEvento(new Event(ACTOR_MOVIDO,new eventoActorMovido(this,dirx, diry)));
						setAnimacion(dirx - xActual,diry - yActual);
					}

				
			}
	}

void Player::render()
	{
			animaciones[actual]->render(this->x, this->y); 
	}
//listener
bool Player::onEvent(Event *e){
	punto *p = NULL;
	eventoPulsacionRaton *eData = NULL;
	eventoRutaGenerada *dataRuta = NULL;
	int dx, dy;
	SenalRuta *senal = NULL;

	switch (e->tipo){
			case CARGANDO_MAPA:
				mapa = ((eventoCargaMapa*)e->datos)->map;
				
				p = mapa->getSpawn(spawn);

				if (p != NULL){
					xDestino = x = p->x - (((int)p->x)%mapa->getAnchoTile());
					yDestino = y = p->y - (((int)p->y)%mapa->getAltoTile());
				}else{
					xDestino = yDestino = x = y = 240.f;
				}

				if (ruta)
					delete ruta;

				ruta = NULL;

				return false;
			break;
			case TRIGGER_ENTRADA:
				spawn = ((eventoTriggerEntrada*)e->datos)->spawn;
			break;
			case RATON_BOTON_SOLTADO:
				eData = (eventoPulsacionRaton *)e->datos;
				
				dx = (-g->getCamara()->getX() + eData->x)/mapa->getAnchoTile();
				dy = (-g->getCamara()->getY() + eData->y)/mapa->getAltoTile();
				
				g->getEventos()->enviarEvento(new Event(PETICION_RUTA,new eventoPeticionRuta(this,x/mapa->getAnchoTile(),y/mapa->getAltoTile(),dx,dy)));

				destinoRatonX = dx * mapa->getAnchoTile();
				destinoRatonY = dy * mapa->getAltoTile();
				
				


			break;
			case RUTA_GENERADA:
				dataRuta = (eventoRutaGenerada*)e->datos;
				if (getID() == dataRuta->actor){

					if (dataRuta->estado == PathFinding::LISTO){
						ruta = dataRuta->ruta;
						senal = new SenalRuta(g->getNewID(),string("data/actores/senalPathfinding.xml"));
						click->play(0.2f);
					}
					else{
						senal = new SenalRuta(g->getNewID(),string("data/actores/senalPathfindingErronea.xml"));
					}
					senal->mover(destinoRatonX,destinoRatonY,0.f);
					g->addActor(senal);
					
				}
				
			break;
		}
	return false;
	}

Player::~Player(void)
	{
	hash_map<string,Animacion*>::iterator it;
		for(it = animaciones.begin(); it != animaciones.end(); ++it)
			delete it->second;
		animaciones.clear();
	}

void Player::seguirPath()
	{
		posicionTile *ps = ruta->getPaso();

		if (ps != NULL)
		{
			moverDestino(ps->x,ps->y,true);
		}
		else
		{
			delete ps; 
			ps = NULL;
		}
	}

void Player::setAnimacion( int dirx, int diry )
	{
		if (dirx > 0)
			actual = "Derecha";
		else if (dirx < 0 )
			actual = "Izquierda";
		else if (diry > 0)
			actual = "Abajo";
		else
			actual = "Arriba";
	}

